{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Coding a spam classifier with naive Bayes\n",
    "\n",
    "### 1. Imports and pre-processing data\n",
    "\n",
    "We load the data into a Pandas DataFrame, and then preprocess it by adding a string with the (non-repeated) lowercase words in the email."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "emails = pd.read_csv('emails.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>text</th>\n",
       "      <th>spam</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Subject: naturally irresistible your corporate...</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Subject: the stock trading gunslinger  fanny i...</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Subject: unbelievable new homes made easy  im ...</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Subject: 4 color printing special  request add...</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Subject: do not have money , get software cds ...</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>Subject: great nnews  hello , welcome to medzo...</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>Subject: here ' s a hot play in motion  homela...</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>Subject: save your money buy getting this thin...</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>Subject: undeliverable : home based business f...</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>Subject: save your money buy getting this thin...</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                                text  spam\n",
       "0  Subject: naturally irresistible your corporate...     1\n",
       "1  Subject: the stock trading gunslinger  fanny i...     1\n",
       "2  Subject: unbelievable new homes made easy  im ...     1\n",
       "3  Subject: 4 color printing special  request add...     1\n",
       "4  Subject: do not have money , get software cds ...     1\n",
       "5  Subject: great nnews  hello , welcome to medzo...     1\n",
       "6  Subject: here ' s a hot play in motion  homela...     1\n",
       "7  Subject: save your money buy getting this thin...     1\n",
       "8  Subject: undeliverable : home based business f...     1\n",
       "9  Subject: save your money buy getting this thin...     1"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "emails[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def process_email(text):\n",
    "    text = text.lower()\n",
    "    return list(set(text.split()))\n",
    "\n",
    "emails['words'] = emails['text'].apply(process_email)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>text</th>\n",
       "      <th>spam</th>\n",
       "      <th>words</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>Subject: naturally irresistible your corporate...</td>\n",
       "      <td>1</td>\n",
       "      <td>[task, have, content, havinq, promise, much, w...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Subject: the stock trading gunslinger  fanny i...</td>\n",
       "      <td>1</td>\n",
       "      <td>[and, not, albeit, hall, deoxyribonucleic, clo...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Subject: unbelievable new homes made easy  im ...</td>\n",
       "      <td>1</td>\n",
       "      <td>[this, and, have, 454, ., unbelievable, -, all...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>Subject: 4 color printing special  request add...</td>\n",
       "      <td>1</td>\n",
       "      <td>[this, and, ca, ., -, is, an, golden, a, adver...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Subject: do not have money , get software cds ...</td>\n",
       "      <td>1</td>\n",
       "      <td>[with, not, cds, have, ., all, compatibility, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>Subject: great nnews  hello , welcome to medzo...</td>\n",
       "      <td>1</td>\n",
       "      <td>[150, have, ., um, felicitation, helter, -, is...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>Subject: here ' s a hot play in motion  homela...</td>\n",
       "      <td>1</td>\n",
       "      <td>[review, heip, reiiance, pians, stocks, forese...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>Subject: save your money buy getting this thin...</td>\n",
       "      <td>1</td>\n",
       "      <td>[this, with, not, have, ., -, is, effect, grea...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>Subject: undeliverable : home based business f...</td>\n",
       "      <td>1</td>\n",
       "      <td>[recognized, i, 70590202251232, home, 5, tfi, ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>Subject: save your money buy getting this thin...</td>\n",
       "      <td>1</td>\n",
       "      <td>[this, with, not, have, ., -, is, effect, grea...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                                text  spam  \\\n",
       "0  Subject: naturally irresistible your corporate...     1   \n",
       "1  Subject: the stock trading gunslinger  fanny i...     1   \n",
       "2  Subject: unbelievable new homes made easy  im ...     1   \n",
       "3  Subject: 4 color printing special  request add...     1   \n",
       "4  Subject: do not have money , get software cds ...     1   \n",
       "5  Subject: great nnews  hello , welcome to medzo...     1   \n",
       "6  Subject: here ' s a hot play in motion  homela...     1   \n",
       "7  Subject: save your money buy getting this thin...     1   \n",
       "8  Subject: undeliverable : home based business f...     1   \n",
       "9  Subject: save your money buy getting this thin...     1   \n",
       "\n",
       "                                               words  \n",
       "0  [task, have, content, havinq, promise, much, w...  \n",
       "1  [and, not, albeit, hall, deoxyribonucleic, clo...  \n",
       "2  [this, and, have, 454, ., unbelievable, -, all...  \n",
       "3  [this, and, ca, ., -, is, an, golden, a, adver...  \n",
       "4  [with, not, cds, have, ., all, compatibility, ...  \n",
       "5  [150, have, ., um, felicitation, helter, -, is...  \n",
       "6  [review, heip, reiiance, pians, stocks, forese...  \n",
       "7  [this, with, not, have, ., -, is, effect, grea...  \n",
       "8  [recognized, i, 70590202251232, home, 5, tfi, ...  \n",
       "9  [this, with, not, have, ., -, is, effect, grea...  "
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "emails[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Number of emails: 5728\n",
      "Number of spam emails: 1368\n",
      "\n",
      "Probability of spam: 0.2388268156424581\n"
     ]
    }
   ],
   "source": [
    "num_emails = len(emails)\n",
    "num_spam = sum(emails['spam'])\n",
    "\n",
    "print(\"Number of emails:\", num_emails)\n",
    "print(\"Number of spam emails:\", num_spam)\n",
    "print()\n",
    "\n",
    "# Calculating the prior probability that an email is spam\n",
    "print(\"Probability of spam:\", num_spam/num_emails)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. Training a naive Bayes model\n",
    "\n",
    "Our plan is to write a dictionary, and in this dictionary record every word, and its pair of occurrences in spam and ham"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = {}\n",
    "\n",
    "# Training process\n",
    "for index, email in emails.iterrows():\n",
    "    for word in email['words']:\n",
    "        if word not in model:\n",
    "            model[word] = {'spam': 1, 'ham': 1}\n",
    "        if word in model:\n",
    "            if email['spam']:\n",
    "                model[word]['spam'] += 1\n",
    "            else:\n",
    "                model[word]['ham'] += 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'spam': 9, 'ham': 1}"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model['lottery']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'spam': 39, 'ham': 42}"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model['sale']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. Using the model to make predictions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "def predict_bayes(word):\n",
    "    word = word.lower()\n",
    "    num_spam_with_word = model[word]['spam']\n",
    "    num_ham_with_word = model[word]['ham']\n",
    "    return 1.0*num_spam_with_word/(num_spam_with_word + num_ham_with_word)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predict_bayes('lottery')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.48148148148148145"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predict_bayes('sale')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 141,
   "metadata": {},
   "outputs": [],
   "source": [
    "def predict_naive_bayes(email):\n",
    "    total = len(emails)\n",
    "    num_spam = sum(emails['spam'])\n",
    "    num_ham = total - num_spam\n",
    "    email = email.lower()\n",
    "    words = set(email.split())\n",
    "    spams = [1.0]\n",
    "    hams = [1.0]\n",
    "    for word in words:\n",
    "        if word in model:\n",
    "            spams.append(model[word]['spam']/num_spam*total)\n",
    "            hams.append(model[word]['ham']/num_ham*total)\n",
    "    prod_spams = np.long(np.prod(spams)*num_spam)\n",
    "    prod_hams = np.long(np.prod(hams)*num_ham)\n",
    "    return prod_spams/(prod_spams + prod_hams)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 143,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9638144992048691"
      ]
     },
     "execution_count": 143,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predict_naive_bayes('lottery sale')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 144,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.12554358867164467"
      ]
     },
     "execution_count": 144,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predict_naive_bayes('Hi mom how are you')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 145,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.12554358867164467"
      ]
     },
     "execution_count": 145,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predict_naive_bayes('Hi MOM how aRe yoU afdjsaklfsdhgjasdhfjklsd')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 146,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6.964603508395967e-05"
      ]
     },
     "execution_count": 146,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predict_naive_bayes('meet me at the lobby of the hotel at nine am')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 147,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.9995234218677428"
      ]
     },
     "execution_count": 147,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predict_naive_bayes('enter the lottery to win three million dollars')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 148,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.999973472265966"
      ]
     },
     "execution_count": 148,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predict_naive_bayes('buy cheap lottery easy money now')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 156,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.4197107645488719"
      ]
     },
     "execution_count": 156,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predict_naive_bayes('Grokking Machine Learning by Luis Serrano')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 157,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.2388268156424581"
      ]
     },
     "execution_count": 157,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predict_naive_bayes('asdfgh')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
